[pull] main from MetaMask:main#730
Merged
Merged
Conversation
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
## **Description**
Bump axios to 1.15.1
<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry:
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: my feature name
Scenario: user [verb for user action]
Given [describe expected initial app state]
When user [verb for user action]
Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [ ] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Low risk dependency bump limited to `axios` via Yarn
resolutions/lockfile, with potential for minor runtime behavior changes
in HTTP requests.
>
> **Overview**
> Updates the Yarn `resolutions` override to `axios@^1.15.1` and
refreshes `yarn.lock` to pull in `axios@1.15.2`.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
c6c6073. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> ## **Description** The Top Traders homepage section would silently disappear whenever the leaderboard API call failed. This happened because the section guard condition treated a failed fetch, where isLoading is false and traders is empty. Identically to a genuinely empty result set, causing return null. We now show the default error state when that happens and while the user Retries the request the skeleton is also activated while the request is in-flight. <img height="800" alt="Simulator Screenshot - iPhone 17 Pro - 2026-04-29 at 16 17 58" src="https://github.com/user-attachments/assets/470ba09e-1bbf-4be5-8365-3a871fb6f8e9" /> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Moderate UI/telemetry change: alters Top Traders section render gating and adds new SocialService error telemetry (Logger extras + Sentry breadcrumbs) across multiple hooks, which could affect user-visible states and error reporting but not security-sensitive logic. > > **Overview** > Prevents the homepage **Top Traders** section from disappearing on leaderboard fetch failures by distinguishing *empty* vs *error* vs *background refetch* states, rendering an `ErrorState` with Retry, and showing skeletons while a retry is in-flight (while keeping cached traders visible on refetch failures). > > Adds shared SocialService telemetry helpers (`socialServiceTelemetry`) and updates Social Leaderboard hooks to emit enriched `Logger.error` extras and Sentry breadcrumbs (including endpoint, coarse error category, and optional HTTP status/query params), with tests updated/expanded accordingly. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit fcbc39b. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until this PR meets the canonical
Definition of Ready For Review in `docs/readme/ready-for-review.md`.
In short: the template must be materially complete (not just section
titles
present), all status checks must be currently passing, and the only
expected
follow-up commits must be reviewer-driven.
-->
## **Description**
Bumps AI-controller version which fixes the "What's Happening" (feature
flag gated) section display error.
<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry: no-changelog
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: my feature name
Scenario: user [verb for user action]
Given [describe expected initial app state]
When user [verb for user action]
Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
<!--
Every checklist item must be consciously assessed before marking this PR
as
"Ready for review". A checked box means you deliberately considered that
responsibility, not that you literally performed every action listed.
Unchecked boxes are ambiguous: they are not an implicit "N/A" and they
are not
a silent "skip". See `docs/readme/ready-for-review.md` for the full
checklist
semantics.
-->
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
#### Performance checks (if applicable)
- [ ] I've tested on Android
- Ideally on a mid-range device; emulator is acceptable
- [ ] I've tested with a power user scenario
- Use these [power-user
SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93)
to import wallets with many accounts and tokens
- [ ] I've instrumented key operations with Sentry traces for production
performance metrics
- See [`trace()`](/app/util/trace.ts) for usage and
[`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274)
for an example
For performance guidelines and tooling, see the [Performance
Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers).
## **Pre-merge reviewer checklist**
<!--
Reviewer checklist items follow the same semantics as the author
checklist: an
unchecked box is ambiguous, a checked box means the reviewer consciously
assessed that responsibility. See `docs/readme/ready-for-review.md`.
-->
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Low risk dependency bump limited to `@metamask/ai-controllers`, but it
can still change runtime behavior in AI/feature-flagged UI flows.
>
> **Overview**
> Updates the `@metamask/ai-controllers` dependency from `^0.6.0` to a
pinned `0.6.3` version.
>
> Refreshes `yarn.lock` accordingly, including updated transitive
requirements (notably `@metamask/messenger` and
`@metamask/base-controller`) for the new `ai-controllers` release.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
812cdb4. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description** **Problem:** iOS yarn cache download stalls account for **28% (~18 runs)** of the 64 Setup Environment CI failures on `main` over 30 days (Mar 16 – Apr 16, 2026). The 610MB yarn cache downloads at 0.3-2.8 MB/s on Cirrus macOS self-hosted runners (`ghcr.io/cirruslabs/macos-runner:tahoe`), with tar extraction sometimes hanging for 9+ minutes until the action times out. See [INFRA-3580](https://consensyssoftware.atlassian.net/browse/INFRA-3580) for the full root cause analysis. **Investigation data:** Examined 6 iOS E2E setup failures from Apr 8-10: | Run | What happened | |-----|---------------| | 24268253971 | Cache hit, 582MB downloaded at ~2.6 MB/s (3.8min), **tar extraction hung 9.4min → timeout** | | 24236471310 | Action timeout during `bundle show cocoapods` | | 24227213798 | Foundry download failure (covered by PR #29255) | | 24226340316 | Generic action timeout | | 24220368199 | **Corepack download stalled** — `repo.yarnpkg.com` hung 4.8min | | 24217223040 | **Corepack download stalled** — same, hung 2.6min | **iOS E2E full setup timing (Cirrus macOS runners):** | Period | Samples | Min | Max | Avg | Median | P95 | |--------|---------|-----|-----|-----|--------|-----| | Apr 8-10 (failure period) | 15 | 180s | 202s | 189s | 187s | 202s | | Apr 22-23 (recent) | 15 | 188s | 267s | 208s | 204s | 267s | iOS setup takes ~2x longer than Android (189-208s vs 103-136s) due to Ruby, Bundler, CocoaPods, and Detox on top of shared steps. **Solution — two changes:** 1. **`restore-keys` fallback** — Currently the yarn cache is exact-match only. On cache miss (e.g., `yarn.lock` changed), it triggers a full 610MB re-download. Adding `restore-keys` lets yarn reuse a stale cache and only update the diff. Pattern already used by Bundler cache in the same file (line 272). 2. **`continue-on-error: true`** — If the cache download or tar extraction stalls, the job currently fails entirely. With `continue-on-error`, a stalled cache is skipped and `yarn install --immutable` runs without cache (slower but succeeds). Pattern already used by CocoaPods specs cache in the same file (line 333). ### Why `restore-keys` is safe The concern: could `restore-keys` restore a stale `node_modules` from `main` with different package versions? **No.** `yarn install --immutable` guarantees that `node_modules` will exactly match `yarn.lock` when it finishes, regardless of cache state. The cache is just a starting point — yarn adds, removes, or changes whatever is needed to reconcile. `--immutable` only prevents `yarn.lock` modifications, not `node_modules` updates. Example: main merges a PR updating package X from v1.0→v1.1. Your PR branch (not rebased) still has X@v1.0 in `yarn.lock`. `restore-keys` restores main's cache with X@v1.1. `yarn install --immutable` runs → installs X@v1.0 per your lockfile. Same outcome as a cold install — the lockfile is always the source of truth. Cache only affects **speed**, not **correctness**. ### `continue-on-error` — needs team input This makes the cache step non-blocking. If the 610MB download stalls or tar extraction hangs (actual observed failure: 9.4min hang), the step fails gracefully and `yarn install --immutable` runs without cache (slower ~60-90s but succeeds). **Pros:** stalled cache no longer kills the job; `yarn install --immutable` still produces correct `node_modules`; pattern already used by CocoaPods specs cache. **Cons:** cache failures become silent (job passes but slower); reduces visibility into cache infra problems. > **This change can be removed from the PR if the team prefers cache-or-fail behavior.** The `restore-keys` change alone still adds value. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: [INFRA-3580](https://consensyssoftware.atlassian.net/browse/INFRA-3580) (partial — addresses iOS yarn cache download stall sub-cause) ## **Manual testing steps** ```gherkin Feature: CI resilience for yarn cache Scenario: Yarn cache miss uses partial match fallback Given yarn.lock has changed since the last cached run When the "Restore Yarn cache" step runs Then it falls back to a partial key match via restore-keys And yarn install only updates the diff instead of full re-download Scenario: Stalled cache download doesn't block the job Given the yarn cache download stalls on a Cirrus macOS runner When the "Restore Yarn cache" step times out Then the step is marked as failed but the job continues (continue-on-error) And yarn install --immutable runs without cache ``` ## **Screenshots/Recordings** N/A — CI workflow changes only, no UI impact. ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). _(N/A — CI workflow YAML only, no application code changes)_ - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable _(N/A — CI workflow configuration, validated by CI run on this PR)_ - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable _(N/A — CI workflow YAML, no code)_ - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. [INFRA-3580]: https://consensyssoftware.atlassian.net/browse/INFRA-3580?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ [INFRA-3580]: https://consensyssoftware.atlassian.net/browse/INFRA-3580?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > CI-only workflow change; it may reduce visibility into cache failures but doesn’t affect runtime code or dependency correctness. > > **Overview** > Improves resilience of the `setup-e2e-env` composite action’s Yarn `node_modules` cache restore. > > The Yarn cache step now uses `restore-keys` to allow partial cache matches when `yarn.lock` changes, and is marked `continue-on-error: true` so cache download/extraction failures don’t fail the job and `yarn install --immutable` can proceed without cache. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 2718150. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…ng (#29334) ## **Description** ### Problem CocoaPods CDN rate limiting accounts for **7% (~4 runs)** of Setup Environment CI failures on `main` over 30 days (Mar 16 – Apr 16, 2026), per INFRA-3580 analysis. The error signatures are: - `CDN: trunk URL couldn't be downloaded ... Response: 429 Too Many Requests` - HTTP/2 framing layer errors during `pod install` ### Root Cause The current flow in `setup-e2e-env/action.yml` **defeats its own CocoaPods specs cache**: 1. `actions/cache@v4` restores `~/.cocoapods/repos` (including trunk specs) — **100% cache hit rate** observed 2. `pod repo remove trunk || true` immediately **deletes** the restored trunk specs 3. `pod install --repo-update` must re-download the **entire** trunk from `cdn.cocoapods.org` — thousands of HTTP requests This maximises CDN pressure on every single iOS CI run, increasing the surface area for 429 rate-limit errors. **When trunk exists locally**, `--repo-update` performs an incremental delta update — minimal CDN requests, fast. **Without trunk** (after removal), `--repo-update` downloads everything from scratch — heavy CDN load, slow, triggers 429s. ### Why `pod repo remove trunk` was added The step was added in PR #28433 (commit `bc06cd5123`, Apr 8, 2026) as part of the macOS Sequoia → Tahoe migration for Xcode 26.x support. It was added proactively with the comment "prevent stale specs" — no review comments discussed the rationale, and no specific CDN failure motivated it. Since Cirrus runners are **ephemeral** (VMs destroyed after each job — [confirmed by Cirrus Labs](https://cirrus-runners.app/): *"Every job is executed in a reproducible isolated environment which is completely destroyed after the job is finished"*), the only way trunk specs exist at the start of `pod install` is via the `actions/cache` restore. There is no leftover state from previous jobs. The `--repo-update` flag already handles staleness by fetching deltas when trunk exists locally. ### Data **Pod install timing (successful runs, with trunk removal + full CDN re-download):** | Run ID | Duration | Notes | |--------|----------|-------| | 24887670082 | 116s (1m 56s) | Full CDN download after trunk removal | | 24887265337 | ~100s | Cache hit, trunk removed, re-downloaded | | 24888574759 | ~120s | Cache hit, trunk removed, re-downloaded | **CocoaPods specs cache hit rate:** 100% (exact or restore-key match in all sampled runs) **Cache flow (current, counterproductive):** - Cache restore: ~1 MB restored from GitHub Actions cache → trunk specs present - `pod repo remove trunk`: deletes restored specs → trunk gone - `pod install --repo-update`: full CDN download → thousands of requests → 429 risk ### Solution 1. **Remove standalone `pod repo remove trunk` step** — let cached specs be used on first attempt for incremental `--repo-update` (low CDN load) 2. **Move trunk removal to `on_retry_command`** — only clean on failure (handles corrupt/stale cache edge case) 3. **Increase `max_attempts` from 2 to 3** — matches other retry steps in the same file; CDN rate limits may need a third attempt 4. **Increase `retry_wait_seconds` from 30 to 60** — CDN 429 backoff windows need longer wait than apt mirror desyncs 5. **Add `::warning::` annotation on retry** — makes CDN failures visible in GitHub Actions UI 6. **Add `COCOAPODS_DISABLE_STATS=true`** — eliminates unnecessary analytics network calls during CI **First attempt (happy path):** cached trunk specs + incremental `--repo-update` → few HTTP requests, low CDN load **On failure:** trunk removed for clean slate → full CDN download on retry, warned in Actions UI **Second/third attempt:** fresh download from CDN with 60s backoff between attempts ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: INFRA-3580 ## **Manual testing steps** N/A — CI infrastructure change. Validated by any iOS E2E workflow run (retry logic is transparent in the happy path). The `pod install` step behavior is identical when the first attempt succeeds. ## **Screenshots/Recordings** ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. Made with [Cursor](https://cursor.com) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes the iOS CI dependency install flow and retry behavior, which could affect build stability if cache state differs from expectations, but it is limited to CI setup and guarded by retries. > > **Overview** > Improves iOS E2E CI CocoaPods installation reliability by **stopping the unconditional `pod repo remove trunk` cleanup** so the restored CocoaPods specs cache can be used on the first `pod install --repo-update` attempt. > > The CocoaPods install retry policy is strengthened (attempts 2→3, wait 30s→60s), and trunk cleanup is moved into `on_retry_command` with a GitHub Actions `::warning::` annotation; `COCOAPODS_DISABLE_STATS=true` is added to reduce extra network calls during CI. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 13ce7a7. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description**
This PR extracts the final Mobile CI status gate into a composite action
while preserving the existing `Check all jobs pass` status check name.
Why:
- The final gate decides whether the workflow should pass after standard
CI, E2E build/test jobs, fork-only skips, and merge queue skips
complete.
- Keeping that logic in a dedicated action makes the workflow easier to
maintain and keeps the pass/fail decision consistent.
What changed:
- Added `.github/actions/ci-status-gate`.
- Updated `.github/workflows/ci.yml` so `Check all jobs pass` calls the
composite action.
- Removed the intermediate `All jobs pass` job.
- Preserved current handling for failed jobs, cancelled jobs, skipped
E2E jobs, fork PR skips, merge queue skips, and E2E readiness blocking.
- Added a step summary table that explains each job result evaluated by
the gate.
## **Changelog**
CHANGELOG entry: null
## **Related issues**
No public issue: CI maintenance refactor.
## **Manual testing steps**
Validated the workflow files locally:
```bash
actionlint -color -config-file .github/actionlint.yaml .github/workflows/ci.yml
ruby -e 'require "yaml"; YAML.load_file(".github/workflows/ci.yml"); YAML.load_file(".github/actions/ci-status-gate/action.yml")'
git diff --check
```
Validated extracted gate behavior in the public test fork:
https://github.com/consensys-test/metamask-mobile-test
- Non-ignorable app-code PR with `pr-not-ready-for-e2e`: `Check all jobs
pass` failed as expected because `block_merge_for_e2e_readiness=true`.
- PR: consensys-test#3
- Gate:
https://github.com/consensys-test/metamask-mobile-test/actions/runs/25321128954/job/74237306086
- Locale-only PR without readiness blocking: E2E build/test jobs
skipped, and the final gate accepted those skips.
- PR: consensys-test#2
- Gate:
https://github.com/consensys-test/metamask-mobile-test/actions/runs/25318425027/job/74223723784
- Locale-only PR with `pr-not-ready-for-e2e`: E2E jobs stayed skipped
and `Check all jobs pass` passed.
- PR: consensys-test#2
- Gate:
https://github.com/consensys-test/metamask-mobile-test/actions/runs/25321510460/job/74234336146
- Standard CI failure: `Check all jobs pass` failed when a required
standard CI job failed.
- PR: consensys-test#4
- Gate:
https://github.com/consensys-test/metamask-mobile-test/actions/runs/25321403908/job/74233562352
- E2E job failure: `Check all jobs pass` failed when an E2E smoke job
failed.
- PR: consensys-test#6
- E2E job:
https://github.com/consensys-test/metamask-mobile-test/actions/runs/25328925239/job/74257209475
- Gate:
https://github.com/consensys-test/metamask-mobile-test/actions/runs/25328925239/job/74259419260
- Build job failure: `Check all jobs pass` failed when an E2E build job
failed.
- PR: consensys-test#5
- Build job:
https://github.com/consensys-test/metamask-mobile-test/actions/runs/25331281786/job/74265395383
- Gate:
https://github.com/consensys-test/metamask-mobile-test/actions/runs/25331281786/job/74267776538
## **Screenshots/Recordings**
### **Before**
N/A
### **After**
N/A
## **Pre-merge author checklist**
- [x] I've followed MetaMask Contributor Docs and MetaMask Mobile Coding
Standards.
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using JSDoc format if applicable
- [x] I've applied the right labels on the PR if applicable.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR where applicable.
- [ ] I confirm that this PR addresses the described change and includes
the necessary testing evidence.
## Description https://consensyssoftware.atlassian.net/browse/RWDS-1239 https://consensyssoftware.atlassian.net/browse/RWDS-1190 https://consensyssoftware.atlassian.net/browse/RWDS-1215 Adds support for the Perps Trading Competition rewards campaign. Users can view campaign details, join via a guided tour, track their stats (rank, PnL, notional volume and margin thresholds), browse the leaderboard, and monitor the prize pool — which scales from \$10k to \$50k based on total notional volume. Geo-restricted users see a locked CTA. Once opted in, the CTA switches to "Open Position" navigating directly to the Perps tab. New screens: campaign details, stats, and full leaderboard. All data-driven from the existing campaign/leaderboard backend infrastructure. ## Changelog CHANGELOG entry: **Added**: Rewards Perps Trading Campaign — details page, stats page, leaderboard page, prize pool, tour, and opt-in flow. ## Screenshots <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-28 at 15 31 25" src="https://github.com/user-attachments/assets/005c0faf-0a1f-4f9e-ade8-68bd4479b6ff" /> ### ----------------------------------------Qualified---------------------------------------- <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-29 at 15 24 21" src="https://github.com/user-attachments/assets/29114a1b-45c3-4a42-b1f1-b8c316163692" /> <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-29 at 15 24 28" src="https://github.com/user-attachments/assets/0f482e11-eff2-463e-b7fb-206f3769a19f" /> <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-28 at 17 28 50" src="https://github.com/user-attachments/assets/e52b7b84-2110-4b1d-b746-695c5ae1a756" /> <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-28 at 17 29 33" src="https://github.com/user-attachments/assets/15e3bdc0-ca0e-4f3b-a968-be2a10639005" /> ### ----------------------------------------Pending---------------------------------------- <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-29 at 15 30 03" src="https://github.com/user-attachments/assets/7b2e1f9c-0344-4f42-8da5-7294441f9fe0" /> <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-29 at 15 28 25" src="https://github.com/user-attachments/assets/3b1953b0-d855-4f82-a31b-fc006ccf8537" /> <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-29 at 15 30 03" src="https://github.com/user-attachments/assets/13481cbd-521b-468b-aa35-20f2500f69c5" /> <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-29 at 15 32 31" src="https://github.com/user-attachments/assets/7a10c0fd-6b48-42d1-b8fd-24edddce7f9f" /> ### ----------------------------------------Split View---------------------------------------- <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-28 at 17 36 22" src="https://github.com/user-attachments/assets/2aeaa9ee-7cff-4757-82c3-1fdcaa381d2e" /> <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-28 at 17 36 38" src="https://github.com/user-attachments/assets/092e8364-3954-45d9-91fc-79c3d20f2942" /> <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-28 at 17 37 38" src="https://github.com/user-attachments/assets/cde2b994-3036-4513-a7c8-d2dd1ee7ce4e" /> <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-28 at 17 50 45" src="https://github.com/user-attachments/assets/286168c1-7096-49d2-af89-e9103abe0ae1" /> <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-04-28 at 18 00 11" src="https://github.com/user-attachments/assets/a7b3c258-120a-42a9-91cf-a67d6bb250dc" /> ### ---------------------------------Powered by HyperTracker------------------------------ <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-05-01 at 11 44 51" src="https://github.com/user-attachments/assets/69f47feb-1d7d-4c3e-ac7e-f1f4c403eac6" /> <img width="1179" height="2556" alt="Simulator Screenshot - E2E Test - 2026-05-01 at 11 44 56" src="https://github.com/user-attachments/assets/41f19668-199d-4acb-8c60-9902a214171e" /> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Adds new Rewards navigation routes and multiple Perps campaign views/CTAs, plus refactors shared leaderboard/prize-pool logic that could affect existing Ondo rendering and testIDs. Risk is moderate due to new conditional UI flows and reused components across campaigns. > > **Overview** > Adds a new **Perps Trading rewards campaign** user flow with dedicated `details`, `leaderboard`, and `stats` screens, wiring them into `RewardsNavigator`, `CampaignTile` navigation (including tour routing), and deeplink handling (`campaign=perps-comp`). > > Refactors campaign UI to improve reuse: extracts a shared `CampaignLeaderboard` (rows/skeleton/separator + shared test IDs) and updates `OndoLeaderboard` to use it; splits `CampaignStatsSummary` into `OndoCampaignStatsSummary` (renamed test IDs) and reuses its `StatCell`/tags in new Perps stats components. > > Unifies prize pool tier computation by introducing `computePrizePoolProgress` and migrating `OndoPrizePool`/`OndoLeaderboardView` off bespoke `getCurrentPrize`/progress logic. Adds extensive test coverage for the new Perps views/components and updated Ondo stats/leaderboard behavior. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit fcf01e2. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: sophieqgu <sophieqgu@gmail.com>
…29607) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> ## **Description** Show 5 year projected balane on money account deposit page. ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/CONF-1296 ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <img width="396" height="854" alt="Screenshot 2026-05-01 at 5 54 30 PM" src="https://github.com/user-attachments/assets/8fd76b2f-92be-437c-a32e-5a203f3d4788" /> ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [X] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [X] I've completed the PR template to the best of my ability - [X] I've included tests if applicable - [X] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [X] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [ ] I've tested on Android - Ideally on a mid-range device; emulator is acceptable - [ ] I've tested with a power user scenario - Use these [power-user SRPs](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk UI-only change that adds a derived display value based on APY; main risk is incorrect math/formatting or missing APY data causing the line to disappear. > > **Overview** > Shows a *projected 5-year balance* line on the custom amount confirmation when the transaction type is `moneyAccountDeposit`, replacing the usual `PayTokenAmount` display in that case. > > Adds a new `ProjectedFiveYearBalance` component that pulls vault APY via `useMoneyAccountBalance`, computes 5-year compounding with `BigNumber`, formats via `useFiatFormatter`, and safely returns `null` for loading/invalid inputs; includes unit tests and a new i18n string `confirm.custom_amount.projected_five_year_balance`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 8c256e1. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…home page redesign enabled (#29100) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** Multiple E2E tests were disabling the `homepageRedesignV1` and `homepageSectionsV1` feature flags to work around the redesigned homepage UI. This caused a test/production parity gap — tests were running against the old homepage while production users see the new redesigned version. This PR removes all `homepageRedesignV1: false` / `homepageSectionsV1: false` mock overrides and adapts the affected tests to work with the new redesigned homepage. The key change is that network switching now requires navigating to `TokensFullView` first (via the Tokens section header) since the network filter control bar only exists there, not on the homepage itself. ### Changes - Removed `homepageRedesignV1` and `homepageSectionsV1` flag overrides from 7 test files and 1 mock helper - Added `navigateToTokensFullView()`, `navigateBackFromTokensFullView()`, and `openNetworkManagerFromHomepage()` methods to the `NetworkManager` page object - Updated network switching flows in `per-dapp-selected-network`, `batch-transaction`, `stake-action-smoke`, `network-manager`, and `network-manager2` specs to go through `TokensFullView` - Added `tapSelectAllPopularNetworks()` steps in `incoming-transactions` tests to handle single-network fixtures - Added Sepolia-specific token fixture via `withTokens()` for the custom network filter test ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: [MMQA-1712](https://consensyssoftware.atlassian.net/browse/MMQA-1712) ## **Manual testing steps** Scenario 1: Network manager tests pass with redesigned homepage - Given the app launches with homepage redesign feature flags enabled (production defaults) - When user navigates to the Tokens section from the homepage - Then the TokensFullView screen is displayed with a network filter control bar - And user can open the network manager and switch networks Scenario 2: Incoming transactions test with single-network fixture - Given the app launches with only Ethereum enabled in the network map - When user navigates to TokensFullView and selects all popular networks - And user navigates back to homepage and taps the Activity tab - Then incoming transactions are displayed correctly Scenario 3: Dapp per-network transaction with redesigned homepage - Given the app is connected to a dapp on a custom Localhost network - When user switches networks via TokensFullView network manager - Then the dapp retains its per-dapp selected network - And transactions are confirmed on the correct network ## **Screenshots/Recordings** ### **Before** <!-- Tests forced homepageRedesignV1: false to use old homepage UI --> ### **After** <!-- Tests use production-default feature flags with redesigned homepage enabled --> ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. [MMQA-1712]: https://consensyssoftware.atlassian.net/browse/MMQA-1712?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk since changes are limited to E2E test code and mocks, but it may cause CI failures if the redesigned homepage navigation or selectors change again. > > **Overview** > Updates multiple mobile E2E smoke specs to run against the **redesigned homepage defaults** by removing overrides that forced `homepageRedesignV1`/`homepageSectionsV1` off. > > Introduces new `NetworkManager` page-object helpers to reach the network filter via `TokensFullView`, and rewires network-switching steps across confirmation, network-manager, stake, and incoming-transactions tests (including selecting *all popular networks* where single-network fixtures would hide activity). > > Adjusts fixtures/mocks to match the new flows (e.g., `withPopularNetworks()` usage, removing explicit `withNetworkEnabledMap` in the mUSD fixture, and updating the mUSD happy-path assertion to the Cash section container). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 61dc1b7. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )